package entity

import (
	"database/sql"
	"github.com/astaxie/beego/orm"
	"github.com/gomodule/redigo/redis"
	"nspel/nspel"
	"strconv"
	"time"
)

type Score struct {
	Id                              int64           `orm:"pk;auto;column(id)"`
	CountryId                       int64           `orm:"column(country_id)"`
	ProvinceId                      int64           `orm:"column(province_id)"`
	CityId                          int64           `orm:"column(city_id)"`
	AreaId                          int64           `orm:"column(area_id)"`
	ExperimentAreaId                int64           `orm:"column(experiment_area_id)"`
	SchoolId                        int64           `orm:"column(school_id)"`
	StudentId                       int64           `orm:"column(student_id)"`
	SchoolRollId                    string          `orm:"column(school_roll_id)"`
	Grade                           string          `orm:"column(grade)"`
	Class                           string          `orm:"column(class)"`
	Nation                          string          `orm:"column(nation)"`
	Sex                             byte            `orm:"column(sex)"`
	Height                          sql.NullFloat64 `orm:"column(height)"`
	Weight                          sql.NullFloat64 `orm:"column(weight)"`
	BodyMassIndex                   sql.NullFloat64 `orm:"column(body_mass_index)"`
	BodyMassIndexBasicScore         sql.NullFloat64 `orm:"column(body_mass_index_basic_score)"`
	BodyMassIndexExtraScore         sql.NullFloat64 `orm:"column(body_mass_index_extra_score)"`
	BodyMassIndexTotalScore         sql.NullFloat64 `orm:"column(body_mass_index_total_score)"`
	BodyMassIndexLevel              sql.NullString  `orm:"column(body_mass_index_level)"`
	VitalCapacity                   sql.NullFloat64 `orm:"column(vital_capacity)"`
	VitalCapacityBasicScore         sql.NullFloat64 `orm:"column(vital_capacity_basic_score)"`
	VitalCapacityExtraScore         sql.NullFloat64 `orm:"column(vital_capacity_extra_score)"`
	VitalCapacityTotalScore         sql.NullFloat64 `orm:"column(vital_capacity_total_score)"`
	VitalCapacityLevel              sql.NullString  `orm:"column(vital_capacity_level)"`
	FiftyMeters                     sql.NullFloat64 `orm:"column(50_meters)"`
	FiftyMetersBasicScore           sql.NullFloat64 `orm:"column(50_meters_basic_score)"`
	FiftyMetersExtraScore           sql.NullFloat64 `orm:"column(50_meters_extra_score)"`
	FiftyMetersTotalScore           sql.NullFloat64 `orm:"column(50_meters_total_score)"`
	FiftyMetersLevel                sql.NullString  `orm:"column(50_meters_level)"`
	SitAndReach                     sql.NullFloat64 `orm:"column(sit_and_reach)"`
	SitAndReachBasicScore           sql.NullFloat64 `orm:"column(sit_and_reach_basic_score)"`
	SitAndReachExtraScore           sql.NullFloat64 `orm:"column(sit_and_reach_extra_score)"`
	SitAndReachTotalScore           sql.NullFloat64 `orm:"column(sit_and_reach_total_score)"`
	SitAndReachLevel                sql.NullString  `orm:"column(sit_and_reach_level)"`
	OneMinuteRopeSkipping           sql.NullFloat64 `orm:"column(1_minute_rope_skipping)"`
	OneMinuteRopeSkippingBasicScore sql.NullFloat64 `orm:"column(1_minute_rope_skipping_basic_score)"`
	OneMinuteRopeSkippingExtraScore sql.NullFloat64 `orm:"column(1_minute_rope_skipping_extra_score)"`
	OneMinuteRopeSkippingTotalScore sql.NullFloat64 `orm:"column(1_minute_rope_skipping_total_score)"`
	OneMinuteRopeSkippingLevel      sql.NullString  `orm:"column(1_minute_rope_skipping_level)"`
	OneMinuteSitUp                  sql.NullFloat64 `orm:"column(1_minute_sit_up)"`
	OneMinuteSitUpBasicScore        sql.NullFloat64 `orm:"column(1_minute_sit_up_basic_score)"`
	OneMinuteSitUpExtraScore        sql.NullFloat64 `orm:"column(1_minute_sit_up_extra_score)"`
	OneMinuteSitUpTotalScore        sql.NullFloat64 `orm:"column(1_minute_sit_up_total_score)"`
	OneMinuteSitUpLevel             sql.NullString  `orm:"column(1_minute_sit_up_level)"`
	ShuttleRun                      sql.NullFloat64 `orm:"column(shuttle_run)"`
	ShuttleRunBasicScore            sql.NullFloat64 `orm:"column(shuttle_run_basic_score)"`
	ShuttleRunExtraScore            sql.NullFloat64 `orm:"column(shuttle_run_extra_score)"`
	ShuttleRunTotalScore            sql.NullFloat64 `orm:"column(shuttle_run_total_score)"`
	ShuttleRunLevel                 sql.NullString  `orm:"column(shuttle_run_level)"`
	StandingLongJump                sql.NullFloat64 `orm:"column(standing_long_jump)"`
	StandingLongJumpBasicScore      sql.NullFloat64 `orm:"column(standing_long_jump_basic_score)"`
	StandingLongJumpExtraScore      sql.NullFloat64 `orm:"column(standing_long_jump_extra_score)"`
	StandingLongJumpTotalScore      sql.NullFloat64 `orm:"column(standing_long_jump_total_score)"`
	StandingLongJumpLevel           sql.NullString  `orm:"column(standing_long_jump_level)"`
	Chinning                        sql.NullFloat64 `orm:"column(chinning)"`
	ChinningBasicScore              sql.NullFloat64 `orm:"column(chinning_basic_score)"`
	ChinningExtraScore              sql.NullFloat64 `orm:"column(chinning_extra_score)"`
	ChinningTotalScore              sql.NullFloat64 `orm:"column(chinning_total_score)"`
	ChinningLevel                   sql.NullString  `orm:"column(chinning_level)"`
	OneThousandMeters               sql.NullFloat64 `orm:"column(1000_meters)"`
	OneThousandMetersBasicScore     sql.NullFloat64 `orm:"column(1000_meters_basic_score)"`
	OneThousandMetersExtraScore     sql.NullFloat64 `orm:"column(1000_meters_extra_score)"`
	OneThousandMetersTotalScore     sql.NullFloat64 `orm:"column(1000_meters_total_score)"`
	OneThousandMetersLevel          sql.NullString  `orm:"column(1000_meters_level)"`
	EightHundredMeters              sql.NullFloat64 `orm:"column(800_meters)"`
	EightHundredMetersBasicScore    sql.NullFloat64 `orm:"column(800_meters_basic_score)"`
	EightHundredMetersExtraScore    sql.NullFloat64 `orm:"column(800_meters_extra_score)"`
	EightHundredMetersTotalScore    sql.NullFloat64 `orm:"column(800_meters_total_score)"`
	EightHundredMetersLevel         sql.NullString  `orm:"column(800_meters_level)"`
	PhysicalBasicScore              sql.NullFloat64 `orm:"column(physical_basic_score)"`
	PhysicalExtraScore              sql.NullFloat64 `orm:"column(physical_extra_score)"`
	PhysicalTotalScore              sql.NullFloat64 `orm:"column(physical_total_score)"`
	PhysicalLevel                   sql.NullString  `orm:"column(physical_level)"`
	BodyFat                         sql.NullFloat64 `orm:"column(body_fat)"`
	BodyFatLevel                    sql.NullString  `orm:"column(body_fat_level)"`
	GripStrength                    sql.NullFloat64 `orm:"column(grip_strength)"`
	GripStrengthLevel               sql.NullString  `orm:"column(grip_strength_level)"`
	ResponseCapability              sql.NullFloat64 `orm:"column(response_capability)"`
	ResponseCapabilityLevel         sql.NullString  `orm:"column(response_capability_level)"`
	BalanceAbility                  sql.NullFloat64 `orm:"column(balance_ability)"`
	BalanceAbilityLevel             sql.NullString  `orm:"column(balance_ability_level)"`
	VerticalJump                    sql.NullFloat64 `orm:"column(vertical_jump)"`
	VerticalJumpLevel               sql.NullString  `orm:"column(vertical_jump_level)"`
	Chinese                         sql.NullFloat64 `orm:"column(chinese)"`
	Math                            sql.NullFloat64 `orm:"column(math)"`
	English                         sql.NullFloat64 `orm:"column(english)"`
	Politics                        sql.NullFloat64 `orm:"column(politics)"`
	History                         sql.NullFloat64 `orm:"column(history)"`
	Geography                       sql.NullFloat64 `orm:"column(geography)"`
	Physics                         sql.NullFloat64 `orm:"column(physics)"`
	Chemistry                       sql.NullFloat64 `orm:"column(chemistry)"`
	Biology                         sql.NullFloat64 `orm:"column(biology)"`
	Science                         sql.NullFloat64 `orm:"column(science)"`
	IsExemption                     bool            `orm:"column(is_exemption)"`
	IsSupplementary                 bool            `orm:"column(is_supplementary)"`
	MissingTestNum                  byte            `orm:"column(missing_test_num)"`
	MeasurementDate                 time.Time       `orm:"column(measurement_date)"`
	CreatedAt                       time.Time       `orm:"auto_now_add;type(datetime);column(created_at)"`
	UpdatedAt                       time.Time       `orm:"auto_now;type(datetime);column(updated_at)"`
}

func (*Score) TableName() string {
	return "score"
}

func init() {
	orm.RegisterModel(new(Score))
}

func (s *Score) SelectAllBySchoolRollIdMeasurementDate(schoolRollId string, measureDate time.Time) error {
	key := "score"
	hashKey := "schoolRollId[" + schoolRollId + "].measurement_date[" + measureDate.String() + "]"
	err := nspel.RedisHgetJson(key, hashKey, s)
	if err == nil {
		return nil
	}
	if err != redis.ErrNil {
		nspel.Error(err)
	}
	s.SchoolRollId = schoolRollId
	s.MeasurementDate = measureDate
	err = nspel.GetOrmEngine().QueryTable(s.TableName()).Filter("school_roll_id", s.SchoolRollId).Filter("measurement_date", s.MeasurementDate.Format("2006-01-02")).One(s)
	if err != nil {
		return err
	}
	nspel.RedisHsetJson(key, hashKey, s)
	return nil
}

func (s *Score) SelectAllBySchoolRollIdLastestMeasurementDate(schoolRollId string) error {
	key := "score"
	hashKey := "schoolRollId[" + schoolRollId + "].measurementDate[latest]"
	err := nspel.RedisHgetJson(key, hashKey, s)
	if err == nil {
		return nil
	}
	if err != redis.ErrNil {
		nspel.Error(err)
	}
	s.SchoolRollId = schoolRollId
	err = nspel.GetOrmEngine().QueryTable(s.TableName()).Filter("school_roll_id", s.SchoolRollId).OrderBy("-measurement_date").One(s)
	if err != nil {
		return err
	}
	nspel.RedisHsetJson(key, hashKey, s)
	return nil
}

func (s *Score) SelectFirstAllByStudentId(studentId int64) error {
	key := "score"
	hashKey := "studentId[" + strconv.FormatInt(studentId, 10) + "]"
	err := nspel.RedisHgetJson(key, hashKey, s)
	if err == nil {
		return nil
	}
	if err != redis.ErrNil {
		nspel.Error(err)
	}
	s.StudentId = studentId
	err = nspel.GetOrmEngine().QueryTable(s.TableName()).Filter("student_id", s.StudentId).One(s)
	if err != nil {
		return err
	}
	nspel.RedisHsetJson(key, hashKey, s)
	return nil
}

func (s *Score) CustomCount(ormEng *orm.QuerySeter, hashKey string) (int64, error) {
	key := "score"
	count, err := nspel.RedisHgetInt64(key, hashKey)
	if err == nil {
		return count, nil
	}
	if err != redis.ErrNil {
		nspel.Error(err)
	}
	count, err = (*ormEng).Count()
	if err != nil {
		return 0, err
	}
	nspel.RedisHsetInt64(key, hashKey, count)
	return count, nil
}

func (s *Score) CustomSelectAll(ormEng *orm.QuerySeter, hashKey string) (scores []Score, err error) {
	key := "score"
	err = nspel.RedisHgetJson(key, hashKey, &scores)
	if err == nil {
		return
	}
	if err != redis.ErrNil {
		nspel.Error(err)
	}
	_, err = (*ormEng).All(&scores)
	if err != nil {
		return
	}
	nspel.RedisHsetJson(key, hashKey, scores)
	return
}

func (s *Score) SelectAllBySchoolId(schoolId int64) (scores []Score, err error) {
	key := "score"
	hashKey := "schoolId[" + strconv.FormatInt(schoolId, 10) + "]"
	err = nspel.RedisHgetJson(key, hashKey, &scores)
	if err == nil {
		return
	}
	if err != redis.ErrNil {
		nspel.Error(err)
	}
	_, err = nspel.GetOrmEngine().QueryTable(s.TableName()).Filter("school_id", schoolId).All(&scores)
	if err != nil || len(scores) == 0 {
		return
	}
	nspel.RedisHsetJson(key, hashKey, scores)
	return
}

func (s *Score) SelectAllById(id int64) (err error) {
	key := "score"
	hashKey := "id[" + strconv.FormatInt(id, 10) + "]"
	err = nspel.RedisHgetJson(key, hashKey, s)
	if err == nil {
		return
	}
	if err != redis.ErrNil {
		nspel.Error(err)
	}
	s.Id = id
	err = nspel.GetOrmEngine().Read(s)
	if err != nil {
		return
	}
	nspel.RedisHsetJson(key, hashKey, s)
	return
}

func (s *Score) Insert() error {
	_, err := nspel.GetOrmEngine().Insert(s)
	return err
}

func (s *Score) Update(columns ...string) error {
	_, err := nspel.GetOrmEngine().Update(s, columns...)
	return err
}

func (s *Score) ImportInsert() error {
	return s.Insert()
}

func (s *Score) ImportUpdate() error {
	err := s.Update("country_id", "province_id", "city_id", "area_id", "experiment_area_id", "school_id", "school_roll_id", "class", "grade", "nation", "sex", "height", "weight", "body_mass_index", "body_mass_index_basic_score", "body_mass_index_extra_score", "body_mass_index_total_score", "body_mass_index_level", "vital_capacity", "vital_capacity_basic_score", "vital_capacity_extra_score", "vital_capacity_total_score", "vital_capacity_level", "50_meters", "50_meters_basic_score", "50_meters_extra_score", "50_meters_total_score", "50_meters_level", "sit_and_reach", "sit_and_reach_basic_score", "sit_and_reach_extra_score", "sit_and_reach_total_score", "sit_and_reach_level", "1_minute_rope_skipping", "1_minute_rope_skipping_basic_score", "1_minute_rope_skipping_extra_score", "1_minute_rope_skipping_total_score", "1_minute_rope_skipping_level", "1_minute_sit_up", "1_minute_sit_up_basic_score", "1_minute_sit_up_extra_score", "1_minute_sit_up_total_score", "1_minute_sit_up_level", "shuttle_run", "shuttle_run_basic_score", "shuttle_run_extra_score", "shuttle_run_total_score", "shuttle_run_level", "standing_long_jump", "standing_long_jump_basic_score", "standing_long_jump_extra_score", "standing_long_jump_total_score", "standing_long_jump_level", "chinning", "chinning_basic_score", "chinning_extra_score", "chinning_total_score", "chinning_level", "1000_meters", "1000_meters_basic_score", "1000_meters_extra_score", "1000_meters_total_score", "1000_meters_level", "800_meters", "800_meters_basic_score", "800_meters_extra_score", "800_meters_total_score", "800_meters_level", "physical_basic_score", "physical_extra_score", "physical_total_score", "physical_level", "body_fat", "body_fat_level", "grip_strength", "grip_strength_level", "response_capability", "response_capability_level", "balance_ability", "balance_ability_level", "vertical_jump", "vertical_jump_level", "chinese", "math", "english", "politics", "history", "geography", "physics", "chemistry", "biology", "science", "is_exemption", "is_supplementary", "missing_test_num", "measurement_date")
	return err
}
